// VBXML.CPP

#include <iostream>
using namespace std;

#include "VBXML/VBXML.h"

XERCES_CPP_NAMESPACE_USE


VBXML_DLL_API int ::br::com::sbVB::VBXML::getNumber3()
{
	return 3;
}

VBXML_DLL_API void ::br::com::sbVB::VBXML::VBXML_initialize()
{
}


// text to unicode
VBXML_DLL_API br::com::sbVB::VBXML::VBStringXML 
br::com::sbVB::VBXML::t2u(const char *s)
{
	if (s==0)
		throw VBException_XML("null string pointer"); 
	XMLCh* retStr = XMLString::transcode(s);
	VBStringXML ret(retStr);

	// cout << "DEBUG: leninside retStr=" << XMLString::stringLen(retStr) << endl;
	// const XMLCh* retStr2 = ret.c_xmlStr();
	// cout << "DEBUG: leninside ret =" << XMLString::stringLen(retStr2) << endl;

	XMLString::release(&retStr);
	return ret;
}

// unicode to text
VBXML_DLL_API br::com::sbVB::VBLib::VBString 
br::com::sbVB::VBXML::u2t(const XMLCh *sxml)
{
	if (sxml==0)
		throw VBException_XML("null xml string pointer"); 

	// VBStringXML debug = unicodeStr;
	// cout << "DEBUG: debug=" << debug.getStringInHex() << endl;

	unsigned len = XMLString::stringLen(sxml);
	// cout << "DEBUG: leninside=" << len << endl;

	char *retStr = XMLString::transcode(sxml);
	*(retStr + len) = 0; // terminator char 1
	// *(retStr + len + 1) = 0; // terminator char 2
	br::com::sbVB::VBLib::VBString ret = retStr;
	XMLString::release(&retStr);
	return ret;

}

VBXML_DLL_API bool 
br::com::sbVB::VBXML::existElement(DOMNode* node,const char* tagName)
{
	using namespace br::com::sbVB::VBLib;
	DOMElement  *element;
	DOMNodeList *myNodeList;

	element = (DOMElement*)node;

	// VBStringXML tagNameXML = t2u(tagName);
	// myNodeList = element->getElementsByTagName(tagNameXML);
	myNodeList = element->getElementsByTagName(t2u(tagName));

	// if list is empty
	// if (myNodeList->item(0) == 0)
	if (myNodeList->getLength() == 0)
		return false;

	return true;

}


VBXML_DLL_API br::com::sbVB::VBLib::VBString 
br::com::sbVB::VBXML::getElementValue(DOMNode* node,const char* tagName)
{
	using namespace br::com::sbVB::VBLib;
	DOMElement  *myElement, *element;
	DOMNodeList *myNodeList;

	element = (DOMElement*)node;

	// VBStringXML tagNameXML = t2u(tagName);
	// myNodeList = element->getElementsByTagName(tagNameXML);
	myNodeList = element->getElementsByTagName(t2u(tagName));

	// if list is empty
	// if (myNodeList->item(0) == 0)
	if (myNodeList->getLength() == 0)
		throw VBException_XML(VBString("No tags of name '") + tagName + VBString("'"));
		// return "";
	
	if ((myNodeList->item(0)->getNodeType() == DOMNode::NodeType::ELEMENT_NODE)
	&& (myNodeList->item(0)->getParentNode() == node))
	{
		myElement = (DOMElement*)myNodeList->item(0);
		return u2t(myElement ->getTextContent());
	}

	// if no return from previous code
	throw VBException_XML("bad return from getElementValue");
	return "";
}

VBXML_DLL_API br::com::sbVB::VBLib::VBString br::com::sbVB::VBXML::getElementValue(DOMNode* node
	,const char* tagName_1,const char* tagName_2)
{
	using namespace br::com::sbVB::VBLib;
	DOMElement  *element = (DOMElement*)node;
	DOMElement  *myElement_1, *myElement_2;
	DOMNodeList *myNodeList_1, *myNodeList_2;

	myNodeList_1 = element->getElementsByTagName(t2u(tagName_1));

	if (myNodeList_1->item(0) == 0)
		throw VBException_XML(VBString("No tags of name '") + tagName_1 + VBString("'"));
	
	if (myNodeList_1->item(0)->getNodeType() == DOMNode::NodeType::ELEMENT_NODE)
	{
		myElement_1 = (DOMElement*)myNodeList_1->item(0);
		myNodeList_2 = myElement_1->getElementsByTagName(t2u(tagName_2));
 				
		if (myNodeList_2->item(0)->getNodeType() == DOMNode::NodeType::ELEMENT_NODE)
		{
			if (myNodeList_2->item(0) == 0)
		throw VBException_XML(VBString("No tags of name '") + tagName_2 + VBString("'"));

			myElement_2 = (DOMElement*)myNodeList_2->item(0);
			return u2t(myElement_2->getTextContent());
		}
	}

	// if no return from previous code
	throw VBException_XML("bad return from getElementValue");
	return "";
}

VBXML_DLL_API br::com::sbVB::VBLib::VBString br::com::sbVB::VBXML::getElementValue(DOMNode* node
	,const char* tagName_1,const char* tagName_2,const char* tagName_3)
{
	using namespace br::com::sbVB::VBLib;
	DOMElement  *element = (DOMElement*)node;;
	DOMElement  *myElement_1, *myElement_2, *myElement_3;
	DOMNodeList *myNodeList_1, *myNodeList_2, *myNodeList_3;

	myNodeList_1 = element->getElementsByTagName(t2u(tagName_1));

	if (myNodeList_1->item(0) == 0)
		return "";

	if (myNodeList_1->item(0)->getNodeType() == DOMNode::NodeType::ELEMENT_NODE)
	{
		myElement_1 = (DOMElement*)myNodeList_1->item(0);
		myNodeList_2 = myElement_1->getElementsByTagName(t2u(tagName_2));
		if (myNodeList_2->item(0)->getNodeType() == DOMNode::NodeType::ELEMENT_NODE)
		{
			if (myNodeList_2->item(0) == 0)
				return "";

			myElement_2 = (DOMElement*)myNodeList_2->item(0);
			myNodeList_3 = myElement_2->getElementsByTagName(t2u(tagName_3));
			if (myNodeList_3->item(0)->getNodeType() == DOMNode::NodeType::ELEMENT_NODE)
			{
				if (myNodeList_3->item(0) == 0)
					return "";

				myElement_3 = (DOMElement*)myNodeList_3->item(0);
				return u2t(myElement_3->getTextContent());
			}

		}
	}

	// if no return from previous code
	return "";
}

VBXML_DLL_API br::com::sbVB::VBLib::VBString 
br::com::sbVB::VBXML::getNthElementValue(XERCES_CPP_NAMESPACE::DOMNode* node,const char* tagName, unsigned i,const char* tagNameInner)
{
	using namespace br::com::sbVB::VBLib;
	using namespace br::com::sbVB::VBXML;
	DOMElement  *element, *ithElement, *innerElement;
	DOMNodeList *myNodeList, *innerNodeList;

	element = (DOMElement*)node;

	// VBStringXML tagNameXML = t2u(tagName);
	// myNodeList = element->getElementsByTagName(tagNameXML);
	myNodeList = element->getElementsByTagName(t2u(tagName));

	// if list is empty
	// if (myNodeList->item(0) == 0)
	if (myNodeList->getLength() < i)
		throw VBException_XML(VBString("No tags of name '") + tagName + VBString("'"));
		// return "";

	// cout << "DEBUG i=" << i << endl;
	
	if ((myNodeList->item(i)->getNodeType() == DOMNode::NodeType::ELEMENT_NODE)
	&& (myNodeList->item(i)->getParentNode() == node))
	{
		ithElement = (DOMElement*)myNodeList->item(i);
		innerNodeList = ithElement->getElementsByTagName(t2u(tagNameInner));
		if ((innerNodeList->item(0)->getNodeType() == DOMNode::NodeType::ELEMENT_NODE)
		&& (innerNodeList->item(0)->getParentNode() == ithElement))
		{
			innerElement = (DOMElement*)innerNodeList->item(0);
			// cout << "DEBUG innerElement=" << (void*)innerElement << endl;
			return (u2t(innerElement->getTextContent()));
		}
	}

	// if no return from previous code
	throw VBException_XML("bad return from getElementValue");
	return "";

}

